﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.IO;
using System.ComponentModel;
using ICSharpCode.SharpZipLib.Zip;
using PTiRouZ.Net.SilverLight.Api;
using PTiRouZ.Net.SilverLight.Api.HelloTipi;
using System.Collections.ObjectModel;


namespace Seesmic.HelloTipi
{

    public class photosUrl
    {
        /// <summary>id de la photo que l'on vient de poster</summary>
        public int id { get; set; }

        /// <summary>url de la miniature de la photo</summary>
        /// <remarks>durée de validité de l'url: 1 heure</remarks>
        public string url_small { get; set; }

        /// <summary>url de la version moyenne de la photo</summary>
        /// <remarks>durée de validité de l'url: 1 heure</remarks>
        public string url_medium { get; set; }

        /// <summary>url de la version large de la photo</summary>
        /// <remarks>durée de validité de l'url: 1 heure</remarks>
        public string url_large { get; set; }

        public string name { get; set; }

        public string extension { get; set; }

        public photosUrl(int _id, string _url_small, string _url_medium, string _url_large)
        {
            id = _id;
            url_small = _url_small;
            url_medium = _url_medium;
            url_large = _url_large;

            name = System.IO.Path.GetFileName(url_large);
            extension = System.IO.Path.GetExtension(url_large);
        }
    }

    public class AlbumDownloadCompletedEventArgs : EventArgs
    {
        public string FileName { get; private set; }

        public AlbumDownloadCompletedEventArgs(string _fileName)
        {
            FileName = _fileName;
        }

    }

    public class TraitementProgressChangedEventArgs : EventArgs
    {
        public int FileTraited { get; private set; }
        public int TotalFileToTraited { get; private set; }

        public TraitementProgressChangedEventArgs(int _FileTraited, int _TotalFileToTraited)
        {
            FileTraited = _FileTraited;
            TotalFileToTraited = _TotalFileToTraited;
        }
                
    }

    public class ArchivePhotos
    {
        private List<photosUrl> PhotoList;

        private SaveFileDialog _saveImageDialog;
        private ZipOutputStream zs;        
        private Stream ZipFileStream;
        private Stream ImgFileStream;


        public event EventHandler<DownloadProgressChangedEventArgs> PhotoDownloadProgressChanged;
        public event EventHandler<TraitementProgressChangedEventArgs> AlbumDownloadProgressChanged;

        public event EventHandler<AlbumDownloadCompletedEventArgs> AlbumDownloadCompleted;


        void OnPhotoDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            EventHandler<DownloadProgressChangedEventArgs> handler = PhotoDownloadProgressChanged;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        void OnAlbumDownloadProgressChanged(object sender, TraitementProgressChangedEventArgs e)
        {
            EventHandler<TraitementProgressChangedEventArgs> handler = AlbumDownloadProgressChanged;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        public ArchivePhotos() { }

        public ArchivePhotos(photo photo)
        {
            PhotoList = new List<photosUrl>();
            PhotoList.Add(new photosUrl(photo.id, photo.url_small, photo.url_medium, photo.url_large));
        }

        public ArchivePhotos(album_photos album_photo)
        {
            PhotoList = new List<photosUrl>();
            PhotoList.Add(new photosUrl(album_photo.id, album_photo.url_small, album_photo.url_medium, album_photo.url_large));
        }
        
        public ArchivePhotos(favourite favimage)
        {
            PhotoList = new List<photosUrl>();
            PhotoList.Add(new photosUrl(favimage.id, favimage.url_small, favimage.url_medium, favimage.url_large));
        }

        public ArchivePhotos(List<favourite> favimages)
        {
            PhotoList = new List<photosUrl>();
            foreach (favourite favimage in favimages)
            {
                PhotoList.Add(new photosUrl(favimage.id, favimage.url_small, favimage.url_medium, favimage.url_large));
            }
        }

        public ArchivePhotos(List<album_photos> photos)
        {
            PhotoList = new List<photosUrl>();
            foreach (album_photos photo in photos)
            {
                PhotoList.Add(new photosUrl(photo.id, photo.url_small, photo.url_medium, photo.url_large));
            }
        }

        public ArchivePhotos(List<photo> photos)
        {
            PhotoList = new List<photosUrl>();
            foreach (photo photo in photos)
            {
                PhotoList.Add(new photosUrl(photo.id, photo.url_small, photo.url_medium, photo.url_large));
            }
        }

        public ArchivePhotos(List<photosUrl> _photosList)
        {
            PhotoList = _photosList;            
        }        

        public bool Execute() {

            _saveImageDialog = new SaveFileDialog();

            if (PhotoList.Count > 1)
            {                
                _saveImageDialog.DefaultExt = ".zip";
                _saveImageDialog.Filter = "Albums Photos Compressé (.zip)|*.zip|Tous les fichiers|*.*";
                _saveImageDialog.FilterIndex = 1;

                bool? open = _saveImageDialog.ShowDialog();
                if (open.HasValue && open.Value)
                {

                    ZipFileStream = _saveImageDialog.OpenFile();
                    OpenZip();

                    downloadPhoto(0);
                }
                else
                    return false;
            }
            else
            {
                _saveImageDialog.DefaultExt = PhotoList[0].extension;
                _saveImageDialog.Filter = "Image (" + PhotoList[0].extension + ")|*" + PhotoList[0].extension + "|Tous les fichiers|*.*";
                _saveImageDialog.FilterIndex = 1;

                bool? open = _saveImageDialog.ShowDialog();
                if (open.HasValue && open.Value)
                {
                    ImgFileStream = _saveImageDialog.OpenFile();

                    LoadFileRequest loadFileRequest = new LoadFileRequest(PhotoList[0].url_large, 0);
                    loadFileRequest.LoadFileRequestCompleted += new EventHandler<LoadFileRequestCompletedEventArgs>(LoadUniqueFileRequestLoadImageRequestCompleted);
                    loadFileRequest.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(OnPhotoDownloadProgressChanged);

                    loadFileRequest.Execute();
                } else
                    return false;
            }
            return true;
        }

        private void downloadPhoto(int index)
        {
            photosUrl photo = PhotoList[index];            

            LoadFileRequest loadFileRequest = new LoadFileRequest(photo.url_large, index);
            loadFileRequest.LoadFileRequestCompleted += new EventHandler<LoadFileRequestCompletedEventArgs>(LoadFileRequestLoadImageRequestCompleted);
            loadFileRequest.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(OnPhotoDownloadProgressChanged);

            loadFileRequest.Execute();

        }

        private void LoadUniqueFileRequestLoadImageRequestCompleted(object sender, LoadFileRequestCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                int length = Convert.ToInt32(e.Result.Length);
                byte[] byteResult = new byte[length];

                try
                {
                    e.Result.Read(byteResult, 0, byteResult.Length);

                    ImgFileStream.Write(byteResult, 0, length);

                    AlbumDownloadCompleted.Invoke(this, new AlbumDownloadCompletedEventArgs(_saveImageDialog.SafeFileName));

                } catch (Exception ex) {                    
                    MessageBox.Show(ex.Message, "Erreur", MessageBoxButton.OK);                    
                }
                finally
                {
                    ImgFileStream.Close();
                }
            }
        }

        private void LoadFileRequestLoadImageRequestCompleted(object sender, LoadFileRequestCompletedEventArgs e)
        {            

            try {
                    if (e.Result != null)
                    {
                        addToZip(zs, e.Result, e.FileName);

                        int index = (sender as LoadFileRequest)._indexFile + 1;

                        AlbumDownloadProgressChanged.Invoke(sender, new TraitementProgressChangedEventArgs(index, PhotoList.Count));                                                
    
                        if (index < PhotoList.Count)
                        {
                            downloadPhoto(index);
                        }
                        else
                        {
                            CloseZip();                            
                        }
                    }
                } catch (Exception ex) {                    
                    MessageBox.Show(ex.Message, "Erreur", MessageBoxButton.OK);                    
                }
        }

        private void OpenZip() {
            zs = new ZipOutputStream(ZipFileStream);
        }

        private void addToZip(ZipOutputStream ZipStream, Stream photoStream, string photoName)
        {            
            int length = Convert.ToInt32(photoStream.Length);
            byte[] byteResult = new byte[length];

            var entry = new ZipEntry(photoName);
            ZipStream.PutNextEntry(entry);

            photoStream.Read(byteResult, 0, byteResult.Length);

            ZipStream.Write(byteResult, 0, length);
        }

        private void CloseZip()
        {
            zs.CloseEntry();
            zs.Close();

            ZipFileStream.Close();

            AlbumDownloadCompleted.Invoke(this, new AlbumDownloadCompletedEventArgs(_saveImageDialog.SafeFileName));           
        } 
    }
}
